package cn.yeziji.forum.utils;

import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.Field;
import java.util.*;

/**
 * Json 工具类
 *
 * @author gzkemays
 * @since 2021/12/24 23:34
 */
public class JsonUtils {
  public static <T> JSONObject parseJsonByPojoHasParent(T data, String... filter) {
    return parseJsonByPoJo(data, true, filter);
  }

  public static <T> JSONObject parseJsonByPojoExParent(T data, String... filter) {
    return parseJsonByPoJo(data, false, filter);
  }

  /**
   * 将 pojo 类 转化为 json
   *
   * @param data 对象
   * @param hasParent 是否包含父级字段
   * @param filter 过滤属性
   * @param <T> 泛型
   * @return json
   */
  private static <T> JSONObject parseJsonByPoJo(T data, boolean hasParent, String... filter) {
    List<String> filters = Arrays.asList(filter);
    Class<?> clazz = data.getClass();
    List<Field> f1 = filterNullField(data, clazz.getDeclaredFields());
    Set<Field> f3 = new HashSet<>(f1);
    if (hasParent) {
      List<Field> f2 = filterNullField(data, clazz.getFields());
      f3.addAll(f2);
    }
    JSONObject json = new JSONObject();
    for (Field field : f3) {
      field.setAccessible(true);
      try {
        String fieldName = field.getName();
        if (!filters.contains(fieldName)) {
          json.put(field.getName(), field.get(data));
        }
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }
    return json;
  }

  /**
   * 过滤空数据
   *
   * @param data 对象
   * @param fields 映射字段
   * @return 字段列表
   */
  private static List<Field> filterNullField(Object data, Field[] fields) {
    List<Field> list = new ArrayList<>();
    for (Field field : fields) {
      field.setAccessible(true);
      try {
        Object obj = field.get(data);
        if (obj == null) {
          continue;
        }
        list.add(field);
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }
    return list;
  }
}
